//
//  HsSecureHander.m
//  hundsun_zjfae
//
//  Created by 王金东 on 14-8-22.
//  Copyright (c) 2014年 王金东. All rights reserved.
//

#import "HsSecureHander.h"

@implementation HsSecureHander

+ (NSData*)AES256Encrypt:(NSString*)strSource withKey:(NSString*)key{
    NSData *dataSource = [strSource dataUsingEncoding:NSUTF8StringEncoding];
    return [dataSource AES256EncryptWithKey:[key md5]];
}

+ (NSString*)AES256Decrypt:(NSData*)dataSource withKey:(NSString*)key{
    NSData *decryptData = [dataSource AES256DecryptWithKey:[key md5]];
    return [[NSString alloc] initWithData:decryptData encoding:NSUTF8StringEncoding];
}

//加密后的_data 转换成 加密后的 NSString
+ (NSString *)dataToString:(NSData *)data{
    NSMutableString *pStr = [[NSMutableString alloc] initWithCapacity: 1];
    UInt8 *p = (UInt8*) [data bytes];
    int len = (int)[data length];
    for(int i = 0; i < len; i ++)
    {
        [pStr appendFormat:@"%02X", *(p+i)];
    }
    return pStr;
}

//加密后的 NSString 转换成 加密后的 NSData
+ (NSData*)stringToNsdata:(NSString* )result{
    const char *buf = [result UTF8String];
    NSMutableData *data2 = [[NSMutableData alloc] init];
    if (buf){
        uint32_t len = (int)strlen(buf);
        
        char singleNumberString[3] = {'\0', '\0', '\0'};
        uint32_t singleNumber = 0;
        for(uint32_t i = 0 ; i < len; i+=2)
        {
            if ( ((i+1) < len) && isxdigit(buf[i]) && (isxdigit(buf[i+1])) )
            {
                singleNumberString[0] = buf[i];
                singleNumberString[1] = buf[i + 1];
                sscanf(singleNumberString, "%x", &singleNumber);
                uint8_t tmp = (uint8_t)(singleNumber & 0x000000FF);
                [data2 appendBytes:(void *)(&tmp)length:1];
            }
            else
            {
                break;
            }
        }
    }
    return data2;
}

@end

#pragma mark ----------------------------
@implementation NSData (CCCryptUtil)

- (NSData*)AES256EncryptWithKey:(NSString*)key {
    NSData *keyDate = [key dataUsingEncoding:NSUTF8StringEncoding];
    //AES256加密，密钥应该是32位的
    //    const void * keyPtr2 = [key bytes];
    //    char ( * keyPtr)[32] = keyPtr2;
    //    bzero(keyPtr, sizeof(keyPtr));
    //对于块加密算法，输出大小总是等于或小于输入大小加上一个块的大小
    //所以在下边需要再加上一个块的大小
    NSUInteger dataLength = [self length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding/*这里就是刚才说到的PKCS7Padding填充了*/| kCCOptionECBMode,
                                          [keyDate bytes], kCCKeySizeAES256,
                                          NULL,/* 初始化向量(可选) */
                                          [self bytes], dataLength,/*输入*/
                                          buffer, bufferSize,/* 输出 */
                                          &numBytesEncrypted);
    
    if (cryptStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }
    free(buffer);//释放buffer
    return nil;
}
- (NSData*)AES256DecryptWithKey:(NSString*)key {
    NSData *keyDate = [key dataUsingEncoding:NSUTF8StringEncoding];
    //同理，解密中，密钥也是32位的
    //    const void * keyPtr2 = [key bytes];
    //    char (*keyPtr)[32] = keyPtr2;
    //对于块加密算法，输出大小总是等于或小于输入大小加上一个块的大小
    //所以在下边需要再加上一个块的大小
    NSUInteger dataLength = [self length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesDecrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding/*这里就是刚才说到的PKCS7Padding填充了*/| kCCOptionECBMode,
                                          [keyDate bytes], kCCKeySizeAES256,
                                          NULL,/* 初始化向量(可选) */
                                          [self bytes], dataLength,/* 输入 */
                                          buffer, bufferSize,/* 输出 */
                                          &numBytesDecrypted);
    if (cryptStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    }
    free(buffer);
    return nil;
}
@end

